import java.util.Arrays;

public class Experiment {


    public static void main(String[] args) {
        System.out.println("一个社会的基尼系数是一个在0~1之间的小数");
        System.out.println("基尼系数为0代表所有人的财富完全一样");
        System.out.println("基尼系数为1代表有一个人掌握了全社会的财富");
        System.out.println("基尼系数越小，代表社会财富分布越均衡；越大则代表财富分布越不均衡");
        System.out.println("在2020年，世界各国的平均基尼系数为0.44");
        System.out.println("目前普遍认为，当基尼系数到达 0.5 时，就意味着社会贫富差距非常大，分布非常不均匀");
        System.out.println("社会可能会因此陷入危机，比如大量的犯罪或者经历社会动荡");
        System.out.println("测试开始");
        int n = 100;//人数
        int t = 1000000;//轮数
        System.out.println("人数 ：" + n);
        System.out.println("轮数 ：" + t);
        experiment(n, t);
        System.out.println("测试结束");
    }

    //实验
    public static void experiment(int n, int t) {
        double[] wealth = new double[n];//用一个数组wealth来记录每个人的财富
        Arrays.fill(wealth, 100);//初始时，每个人的财富都是100
        boolean[] hasMoney = new boolean[n];//判断一个人是否有钱
        for (int i = 0; i < t; i++) {
            //每一轮先判断每个人是否有钱
            Arrays.fill(hasMoney, false);//初始化是假设所有人都没有钱
            for (int j = 0; j < n; j++) {
                if (wealth[j] > 0) {
                    hasMoney[j] = true;//如果有钱就将该下标的数组值改成true
                }
            }

            for (int j = 0; j < n; j++) {
                //如果这个人有钱，就将这个人的1块钱随机给另一个人
                if (hasMoney[j]) {
                    int other = j;//被给钱的人的编号，先将它初始化为自己
                    //如果被给钱的人是给钱的人自己，那么就在0 ~ n-1随机一个编号，直到这个编号的人不是自己
                    do {
                        //(int) (Math.random(） * n);
                        //表示生成一个0 ~ n -1的等概率随机整数
                        other = (int) (Math.random() * n);
                    } while (other == j);
                    wealth[j]--;//给钱人的财富减一
                    wealth[other]++;//被给钱的人财富加一
                }
            }
        }
        //对财富多少进行排序，打印每个人的财富
        Arrays.sort(wealth);
        System.out.println("列出每个人的财富（从贫穷到富有）");
        for (int i = 0; i < wealth.length; i++) {
            System.out.print((int) wealth[i] + " ");
            if (i % 10 == 9) {
                System.out.println();
            }
        }
        System.out.println();
        System.out.println("这个社会的基尼系数为：" + calculateGini(wealth));
    }

    //计算基尼系数
    public static double calculateGini(double[] wealth) {
        double sumOfAbsoluteDifferences = 0;//每个人财富差值的绝对值的总和
        double sumOfWealth = 0;
        for (int i = 0; i < wealth.length; i++) {
            //遍历记录每个人财富的数组，计算sumOfWealth
            sumOfWealth += wealth[i];
            for (int j = 0; j < wealth.length; j++) {
                //计算sumOfAbsoluteDifferences
                sumOfAbsoluteDifferences += Math.abs(wealth[i] - wealth[j]);//下标i位置的财富与下标为j位置的财富差值的绝对值
            }
        }
        return sumOfAbsoluteDifferences / (2 * wealth.length * sumOfWealth);//基尼系数表达式
    }


}
